package com.jebel.framwork.common.util;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;

public class DateUtil {

    public static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_YYYYMMddHHmmss = "yyyyMMddHHmmss";
    public static final String PATTERN_YYYY_MM = "yyyy-MM";
    public static final String PATTERN_YYYY_MM_dd = "yyyy-MM-dd";
    public static final String PATTERN_YYYYMMdd = "yyyyMMdd";
    public static final String PATTERN_YYYYMM = "yyyyMM";

    /**
     * 日期上增加分钟
     *
     * @param date
     * @param amount
     * @return
     */
    public static Date addMinutes(Date date, int amount) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, amount);
        return c.getTime();
    }

    /**
     * 将日期转字符
     *
     * @param date
     * @return
     */
    public static String parseDate2String(Date date) {
        return new SimpleDateFormat(DEFAULT_PATTERN).format(date);
    }

    public static String parseDate2Forat(Date date, String forat) {
        return new SimpleDateFormat(forat).format(date);
    }

    /**
     * 格式化String时间
     *
     * @param time       String类型时间
     * @param timeFromat String类型格式
     * @return 格式化后的Date日期
     */
    public static Date parse2Date(String time, String timeFromat) {
        if (time == null || "".equals(time)) {
            return null;
        }
        Date date = null;
        try {
            date = new SimpleDateFormat(timeFromat).parse(time);
        } catch (Exception e) {

        }
        return date;
    }

    /**
     * 次月第一天
     *
     * @param date
     * @return
     */
    public static Date firstDayOfMonth(Date date) {
        Date firstDayOfMonth = null;
        try {
            if (date == null || "".equals(date)) {
                date = new Date();
            }
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.MONTH, 1);
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            firstDayOfMonth = calendar.getTime();
        } catch (Exception e) {
        }
        return firstDayOfMonth;
    }

    /**
     * 将字符串转成日期
     *
     * @param str
     * @return
     */
    public static String stringDataFormat(String str, String sourceFormat, String needFormat) {
        SimpleDateFormat format = new SimpleDateFormat(sourceFormat);
        Date date = null;
        try {
            date = format.parse(str);
            return new SimpleDateFormat(needFormat).format(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static Long paraseString2Long(String date) {
        Long d = 0L;
        try {
            d = new SimpleDateFormat(DEFAULT_PATTERN).parse(date).getTime();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return d;
    }

    /**
     * 获取两个日期之间的不同月份
     *
     * @param beginDate
     * @param endDate
     * @param separator
     * @return
     */
    public static List<String> getDistMonthListOfDate(Date beginDate, Date endDate, String separator) {
        // 返回的月份列表
        String sRet = "";
        GregorianCalendar beginGC = null;
        GregorianCalendar endGC = null;
        List<String> list = new ArrayList<String>();
        if (separator == null) {
            separator = "-";
        }
        try {
            // 设置日历
            beginGC = new GregorianCalendar();
            beginGC.setTime(beginDate);

            endGC = new GregorianCalendar();
            endGC.setTime(endDate);

            // 直到两个时间相同
            String monthStr = "";
            while (beginGC.getTime().compareTo(endGC.getTime()) <= 0) {
                int month = beginGC.get(Calendar.MONTH) + 1;
                if (month < 10) {
                    monthStr = "0" + month;
                } else {
                    monthStr = month + "";
                }
                if (!list.contains(monthStr)) {
                    list.add(monthStr);
                }
                // 以月为单位，增加时间
                beginGC.add(Calendar.MONTH, 1);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 解析两个日期之间的所有月份
     *
     * @param beginDateStr 开始日期
     * @param endDateStr   结束日期
     * @param separator    默认"-",返回格式,如传"-"则返回yyyy-MM形式
     * @param format       日期格式
     * @return yyyy+separator+MM 格式日期集合
     */
    public static List<String> getDistMonthListOfDate2(String beginDateStr, String endDateStr, String separator, String format) {
        // 指定要解析的时间格式
        DateFormat f = new SimpleDateFormat(format);
        // 定义一些变量
        Date beginDate = null;
        Date endDate = null;

        try {
            // 将字符串parse成日期
            beginDate = f.parse(beginDateStr);
            endDate = f.parse(endDateStr);
            return getDistMonthListOfDate(beginDate, endDate, separator);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 解析两个日期之间的所有月份
     *
     * @param beginDate 开始日期
     * @param endDate   结束日期
     * @param separator 默认"-",返回格式,如传"-"则返回yyyy-MM形式
     * @return MM 格式日期集合
     */
    public static List<String> getMonthListOfDate(Date beginDate, Date endDate, String separator) {
        // 返回的月份列表
        String sRet = "";
        GregorianCalendar beginGC = null;
        GregorianCalendar endGC = null;
        List<String> list = new ArrayList<String>();
        if (separator == null) {
            separator = "-";
        }
        try {
            // 设置日历
            beginGC = new GregorianCalendar();
            beginGC.setTime(beginDate);

            endGC = new GregorianCalendar();
            endGC.setTime(endDate);

            // 直到两个时间相同
            String monthStr = "";
            while (beginGC.getTime().compareTo(endGC.getTime()) <= 0) {
                int month = beginGC.get(Calendar.MONTH) + 1;
                if (month < 10) {
                    monthStr = "0" + month;
                } else {
                    monthStr = month + "";
                }
                sRet = beginGC.get(Calendar.YEAR) + separator + monthStr;
                list.add(sRet);
                // 以月为单位，增加时间
                beginGC.add(Calendar.MONTH, 1);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 解析两个日期之间的所有月份
     *
     * @param beginDateStr 开始日期
     * @param endDateStr   结束日期
     * @param separator    默认"-",返回格式,如传"-"则返回yyyy-MM形式
     * @param format       日期格式
     * @return MM 格式日期集合
     */
    public static List<String> getMonthListOfDate2(String beginDateStr, String endDateStr, String separator, String format) {
        // 指定要解析的时间格式
        DateFormat f = new SimpleDateFormat(format);
        // 定义一些变量
        Date beginDate = null;
        Date endDate = null;

        try {
            // 将字符串parse成日期
            beginDate = f.parse(beginDateStr);
            endDate = f.parse(endDateStr);
            return getMonthListOfDate(beginDate, endDate, separator);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 获取指定时间的那天 00:00:00.000 的时间
     *
     * @param date
     * @return
     */
    public static Date getDayBeginTime(final Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        return c.getTime();
    }

    /**
     * 获取指定时间的那天 23:59:59.999 的时间
     *
     * @param date
     * @return
     */
    public static Date getDayEndTime(final Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MILLISECOND, 999);
        return c.getTime();
    }

    /**
     * 获得两个时间相差(天/时/分/秒)
     *
     * @param one  时间参数 1 格式：1990-01-01 12:00:00
     * @param two  时间参数 2 格式：2009-01-01 12:00:00
     * @param type type=1->天，type=2->时,type=3->分，type=4->秒,其他->间隔的时间串
     * @return long 返回值为：type=1->天，type=2->时,type=3->分，type=4->秒,其他->间隔的时间串
     */
    public static long getDistanceTime(Date one, Date two, int type) {
        long result = 0;
        try {
            long time1 = one.getTime();
            long time2 = two.getTime();
            long diff;
            if (time1 < time2) {
                diff = time2 - time1;
            } else {
                diff = time1 - time2;
            }
            if (type == 1) {//天
                result = diff / (24 * 60 * 60 * 1000);
            } else if (type == 2) {//时
                result = diff / (60 * 60 * 1000);
            } else if (type == 3) {//分
                result = (diff / (60 * 1000));
            } else if (type == 4) {//秒
                result = (diff / 1000);
            } else {
                result = diff;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * LocalDateTime TO Date
     *
     * @param localDateTime
     * @return
     */
    public static Date localDateTime2Date(LocalDateTime localDateTime) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId);
        return Date.from(zonedDateTime.toInstant());
    }

    public static Date localDate2Date(LocalDate localDate) {
        ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
        Instant instant = zonedDateTime.toInstant();
        return Date.from(instant);
    }

    /**
     * 是否是月末最后一天
     *
     * @param date
     * @return
     */
    public static boolean isLastDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, (calendar.get(Calendar.DATE) + 1));
        if (calendar.get(Calendar.DAY_OF_MONTH) == 1) {
            return true;
        }
        return false;
    }



    /**
     * 根据身份证号计算年龄
     * @param pensonnelIdCard
     * @return
     */
    public static Integer getPersonAgeFromIdCard(String pensonnelIdCard) {

        //截取身份证中出行人出生日期中的年、月、日
        Integer personYear = Integer.parseInt(pensonnelIdCard.substring(6, 10));
        Integer personMonth = Integer.parseInt(pensonnelIdCard.substring(10, 12));
        Integer personDay = Integer.parseInt(pensonnelIdCard.substring(12, 14));

        Calendar cal = Calendar.getInstance();
        // 得到当前时间的年、月、日
        Integer yearNow = cal.get(Calendar.YEAR);
        Integer monthNow = cal.get(Calendar.MONTH) + 1;
        Integer dayNow = cal.get(Calendar.DATE);

        // 用当前年月日减去生日年月日
        Integer yearMinus = yearNow - personYear;
        Integer monthMinus = monthNow - personMonth;
        Integer dayMinus = dayNow - personDay;

        Integer age = yearMinus; //先大致赋值

        if (yearMinus == 0) { //出生年份为当前年份
            age = 0;
        }else{ //出生年份大于当前年份
            if (monthMinus < 0) {//出生月份小于当前月份时，还没满周岁
                age = age - 1;
            }
            if (monthMinus == 0) {//当前月份为出生月份时，判断日期
                if (dayMinus < 0) {//出生日期小于当前月份时，没满周岁
                    age = age - 1;
                }
            }
        }
        return age;
    }
}



